package proj2501.main_frame;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;

import proj2501.simple_module.HomePanel;

public class MainFrame extends JFrame {
	private JMenuBar menuBar;
	private MainFramePanel panel;
	
	public MainFrame() {
		System.out.println("Executing MainFrame constructor.");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setTitle("My Window!");
		menuBar = new MainMenuBar(this);
		setJMenuBar(menuBar);
		
		JRootPane rootPane = getRootPane();
		InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
		ActionMap actionMap = rootPane.getActionMap();
		inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "Back");
		actionMap.put("Back", new AbstractAction() {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.out.println("Executing Escape key action.");
				Component component = panel.getComponent(0);
				if (component instanceof HomePanel) {
					closeAction.actionPerformed(null);
				} else {
					goToHomeAction.actionPerformed(null);
				}
			}
		});
		inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0), "F11");
		actionMap.put("F11", new AbstractAction() {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.out.println("Executing F11 key action.");
				toggleFullScreenAction.actionPerformed(null);
			}
		});
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.out.println("MainFramePanel received windowClosing event.");
			}
			@Override
			public void windowClosed(WindowEvent e) {
				System.out.println("MainFramePanel received windowClosed event.");
			}
		});
		
		// Debugs about component focuses.
//		new Timer(5000, new ActionListener() {
//			@Override
//			public void actionPerformed(ActionEvent e) {
//				System.out.println("Current Focus Owner: " + MainFrame.this.getFocusOwner());
//			}
//		}).start();
		
		panel = new MainFramePanel();
		add(panel);
		pack();
		setVisible(true);
	}
	
	@Override
	public void dispose() {
		System.out.println("Executing MainFrame - dispose method.");
		super.dispose();
	}
	
	private static class MainFramePanel extends JPanel {
		private HomePanel homePanel;
		public MainFramePanel() {
			System.out.println("Executing MainFramePanel constructor.");
			setPreferredSize(new Dimension(400, 400));
			setLayout(new BorderLayout());
			homePanel = new HomePanel();
			add(homePanel);
			
			addComponentListener(new ComponentListener() {
				@Override
				public void componentShown(ComponentEvent e) {
					System.out.println("MainFramePanel received componentShown event.");
				}
				
				@Override
				public void componentResized(ComponentEvent e) {
					Dimension newSize = e.getComponent().getSize();
					int width = newSize.width;
					int height = newSize.height;
					String s = "MainFramePanel received componentResized event.";
					s += " (new size: " + width + ", " + height + ")";
					System.out.println(s);
				}
				
				@Override
				public void componentMoved(ComponentEvent e) {
					System.out.println("MainFramePanel received componentMoved event.");
				}
				
				@Override
				public void componentHidden(ComponentEvent e) {
					System.out.println("Execing MainFramePanel received componentHidden event.");
				}
			});
		}
		
		private int numRepaint;
		@Override
		public void repaint(long tm, int x, int y, int width, int height) {
			// Initializes a counter here; to prepare for call from super class constructor.
			if (numRepaint == 0) {
				numRepaint = 1;
			}
			System.out.println("Executing MainFramePanel - repaint method (" + numRepaint++ + ").");
			super.repaint(tm, x, y, width, height);
		}
		
		private int numPaint = 1;
		@Override
		protected void paintComponent(Graphics g) {
			System.out.println("Executing MainFramePanel - paintComponent method (" + numPaint++ + ").");
			super.paintComponent(g);
			g.drawOval(0, 0, 100, 100);
			g.drawOval(0, 0, 200, 200);
			g.drawOval(0, 0, 400, 400);
		}
	}
	
	public CloseAction closeAction = new CloseAction();
	private class CloseAction extends AbstractAction {
		public CloseAction() {
			super("Quit Program");
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			System.out.println("Executing CloseAction - actionPerformed method.");
			MainFrame frame = MainFrame.this;
			frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
		}
	}
	
	private boolean isFullScreen;
	public ToggleFullScreenAction toggleFullScreenAction = new ToggleFullScreenAction();
	public class ToggleFullScreenAction extends AbstractAction {
		public ToggleFullScreenAction() {
			super("Toggle Full Screen Mode (F11)");
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			System.out.println("Executing ToggleFullScreenAction - actionPerformed method.");
			MainFrame frame = MainFrame.this;
			int closeOperation = frame.getDefaultCloseOperation();
			GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
			GraphicsDevice device = environment.getDefaultScreenDevice();
			boolean isFullScreenSupported = device.isFullScreenSupported();
			
			if (isFullScreen) {
				System.out.println("Exiting full-screen mode.");
				device.setFullScreenWindow(null);
				frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
				frame.dispose();
				frame.setDefaultCloseOperation(closeOperation);
				frame.setUndecorated(false);
				frame.setResizable(true);
				frame.menuBar.setVisible(true);
				frame.setVisible(true);
				frame.repaint();
				isFullScreen = false;
			} else {
				System.out.println("Entering full-screen mode.");
				System.out.println("isFullScreenSupported: " + isFullScreenSupported);
				frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
				frame.dispose();
				frame.setDefaultCloseOperation(closeOperation);
				frame.setUndecorated(true);
				frame.setResizable(false);
				frame.menuBar.setVisible(false);
//				frame.setVisible(true);
				device.setFullScreenWindow(frame);
				isFullScreen = true;
			}
		}
	}
	
	public GoToHomeAction goToHomeAction = new GoToHomeAction();
	public class GoToHomeAction extends AbstractAction {
		public GoToHomeAction() {
			super("Go to Home (ESC)");
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			Component component = panel.getComponent(0);
			if (component instanceof HomePanel) {
				return;
			}
			panel.remove(component);
			panel.add(panel.homePanel);
			panel.validate();
			panel.repaint();
		}
	}

}
